iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0

今天就要來模仿 [Day 20] 使用第三方庫--以OpenCV為例 中的OpenCV的作法,使用者只需要知道像以下這樣包含OpenCV的庫路徑與library的路徑,就可以使用OpenCV提供的函式庫了!這樣不僅方便還不容易出錯。

include_directories(${OpenCV_INCLUDE_DIRS})
# 將 OpenCV 的 include 路徑加入到專案中
add_executable(main src/main.cpp)
# 將 main.cpp 編譯成可執行文件 main
target_link_libraries(main ${OpenCV_LIBS})
# 將 OpenCV 的 library 路徑加入到專案中

語法

configure_package_config_file(<input> <output>
  INSTALL_DESTINATION <path>
  [PATH_VARS <var1> <var2> ... <varN>]
  )

input : 輸入文件,通常名為 xxxConfig.cmake.in

output : 輸出文件,通常名為 xxxConfig.cmake,find_package就是透過這個文件來找到第三方庫的。

INSTALL_DESTINATION : 安裝路徑,通常位於 usr/local/lib/cmake 中(在這裡也可以發現前兩天裝的 Opencv) 
或者是 usr/local/share/cmake 中(在這裡可以發現nlohmann_json),這些都是 find_package 預設會搜尋的路徑,在 Day 19有介紹過。

PATH_VARS <var1> <var2>... : 用CMake中的 var1、var2...變數替換xxxConfig.cmake.in文件中的 @var1@、@var2@...。

範例

先利用 set() 函數設定一些要替換掉 Config.cmake.in 文件中的變數,
再生成 Config.cmake 檔。

  1. 編寫 MathFunctions / CMakeLists.txt
set(PACKAGE_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
# 設定要替換Config.cmake.in文件中的@PACKAGE_INCLUDE_DIRS@變數
set(PACKAGE_LIBRARY_DIRS ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
# 設定要替換Config.cmake.in文件中的@PACKAGE_LIBRARY_DIRS@變數
set(PACKAGE_LIBS mysqrt)
# 設定要替換Config.cmake.in文件中的@PACKAGE_LIBS@變數

include(CMakePackageConfigHelpers)
configure_package_config_file(
	${PROJECT_SOURCE_DIR}/Config.cmake.in
	${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
	INSTALL_DESTINATION lib/cmake/${PROJECT_NAME}
	PATH_VARS PACKAGE_INCLUDE_DIRS PACKAGE_LIBRARY_DIRS PACKAGE_LIBS
)
install(FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake DESTINATION lib/cmake/${PROJECT_NAME})
# 讀入 ${PROJECT_SOURCE_DIR}/Config.cmake.in 文件
# 生成 ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake 文件
# 將生成出的 Config.cmake 安裝到 /usr/local/lib/cmake/${PROJECT_NAME},讓find_package能夠在預設的搜索路徑找到
# 替換 ${PROJECT_SOURCE_DIR}/Config.cmake.in 文件中的 @PACKAGE_INCLUDE_DIRS@ @PACKAGE_LIBRARY_DIRS@ @PACKAGE_LIBS@ 變數
  1. 編寫 MathFunctions / Config.cmake.in
@PACKAGE_INIT@

set( @PROJECT_NAME@_INCLUDE_DIRS  @PACKAGE_INCLUDE_DIRS@)
# 相當於 set(MathFunctions_INCLUDE_DIRS ${PACKAGE_INCLUDE_DIRS}})
set( @PROJECT_NAME@_LIBRARY_DIRS @PACKAGE_LIBRARY_DIRS@)
# 相當於 set(MathFunctions_LIBRARY_DIRS ${PACKAGE_LIBRARY_DIRS}})
set( @PROJECT_NAME@_LIBS  @PACKAGE_LIBS@)
# 相當於 set(MathFunctions_LIBS ${PACKAGE_LIBS})

check_required_components(${PROJECT_NAME})
  1. 編譯並安裝

$ cd build
$ cmake ..
$ make
$ sudo make install

kai@esoc:~/2023_iT_CMake/Day23/MathFunctions/build$ sudo make install
Consolidate compiler generated dependencies of target mysqrt
[100%] Built target mysqrt
Install the project...
-- Install configuration: ""
-- Up-to-date: /usr/local/include/mysqrt.h
-- Up-to-date: /usr/local/lib/libmysqrt.so.1.0.0
-- Up-to-date: /usr/local/lib/libmysqrt.so.1
-- Up-to-date: /usr/local/lib/libmysqrt.so
-- Up-to-date: /usr/local/lib/cmake/MathFunctions/MathFunctionsConfig.cmake <---產生的Config.cmake檔案⭐
  1. 編寫 Main / CMakeLists.txt
    將find_package找到MathFunctions後,利用MathFunctions提供的資訊來設定如何編譯。
    這些資訊的來源就是來自於剛剛設定的變數。
find_package(MathFunctions REQUIRED)
# 尋找MathFunctionsConfig.cmake

message(STATUS "MathFunctions_FOUND: ${MathFunctions_FOUND}")
message(STATUS "MathFunctions_INCLUDE_DIRS: ${MathFunctions_INCLUDE_DIRS}")
message(STATUS "MathFunctions_LIBRARY_DIRS: ${MathFunctions_LIBRARY_DIRS}")
message(STATUS "MathFunctions_LIBS: ${MathFunctions_LIBS}")
# 顯示MathFunctions提供的資訊

include_directories(${MathFunctions_INCLUDE_DIRS})
add_executable(main src/main.cpp)
# 將main.cpp編譯成可執行文件main
target_link_directories(main PUBLIC ${MathFunctions_LIBRARY_DIRS})
# 將MathFunctions_LIBRARY_DIRS加入main的連結路徑
target_link_libraries(main PUBLIC ${MathFunctions_LIBS})
# 將MathFunctions的庫鍊結到執行檔main
  1. 編譯與執行

$ cd Main/build
$ cmake ..

kai@esoc:~/2023_iT_CMake/Day23/Main/build$ cmake ..
-- The CXX compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- MathFunctions_FOUND: 1  <----- 使否找到MathFunctions⭐
-- MathFunctions_INCLUDE_DIRS: /usr/local/include   <----- MathFunctions的標頭檔路徑⭐
-- MathFunctions_LIBRARY_DIRS: /usr/local/lib   <----- MathFunctions的庫文件路徑⭐
-- MathFunctions_LIBS: mysqrt   <----- 可供鍊結的庫⭐
-- Configuring done
-- Generating done
-- Build files have been written to: /home/kai/2023_iT_CMake/Day23/Main/build

$ make
$ ./main 10

kai@esoc:~/2023_iT_CMake/Day23/Main/build$ ./main 10
0Computing sqrt of 10 to be 5.5
1Computing sqrt of 10 to be 3.65909
2Computing sqrt of 10 to be 3.19601
3Computing sqrt of 10 to be 3.16246
4Computing sqrt of 10 to be 3.16228
The square root of 10 is 3.16228

🎉完成啦!🎉


上一篇
[Day 22] 製作第三方庫(一)
下一篇
[Day 24] 製作第三方庫( 三)
系列文
建構屬於自己的C/C++專案 : 我的30天CMake學習之旅29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言